﻿#ifndef _SQLQUERY_H_H_
#define _SQLQUERY_H_H_

#include "udatabase/sqlutility.h"
#include "udatabase/sqldatabase.h"
#include "kernel/Referenced.h"

namespace FD{
	namespace Utility{
		namespace DB{

			class CSqlDriver;
			class CSqlResult;
			class CSqlRecord;
			class CSqlQueryPrivate;
			enum JASBatchExecutionMode
			{
				ValuesAsRows,
				ValuesAsColumns
			};
			///<summary>
			///提供执行和生成sql语句的方法
			///</summary>
			class FD_DB_Export CSqlQuery :  public FD::Kernel::CReferenced
			{
			public:
				///<summary>
				///构造函数
				///</summary>
				///<param name="r">result指针</param>
				///<returns><returns>
				CSqlQuery(FD::Utility::DB::CSqlResult *r);
				///<summary>
				///构造函数
				///</summary>
				///<param name=""></param>
				///<returns><returns>
				CSqlQuery();
				///<summary>
				///构造函数
				///</summary>
				///<param name="query">sql语句</param>
				///<returns><returns>
				CSqlQuery(const FD::Kernel::FdUnicodeString& query);
				///<summary>
				///构造函数
				///</summary>
				///<param name="query">sql语句</param>
				///<param name="db">数据库连接对象</param>
				///<returns><returns>
				CSqlQuery(const FD::Kernel::FdUnicodeString& query, FD::Utility::DB::CSqlDatabase db);
				///<summary>
				///显示构造函数
				///</summary>
				///<param name="query">数据库连接对象</param>
				///<returns><returns>
				explicit CSqlQuery(FD::Utility::DB::CSqlDatabase db);
				///<summary>
				///默认构造函数
				///</summary>
				///<param name="other">query对象</param>
				///<returns><returns>
				CSqlQuery(const CSqlQuery& other);
				///<summary>
				///重载赋值操作符
				///</summary>
				///<param name="other">query对象</param>
				///<returns><returns>
				FD::Utility::DB::CSqlQuery& operator=(const FD::Utility::DB::CSqlQuery& other);
				///<summary>
				///析构函数
				///</summary>
				///<param name=""></param>
				///<returns><returns>
				~CSqlQuery();

				///<summary>
				/// 绑定数据到指定的位置
				/// </summary>
				/// <param name="placeholder">绑定位置的占位符</param>
				/// <param name="val">待绑定的数据</param>
				/// <param name="type">绑定类型</param>
				///<returns>void</returns>
				void bindValue(const FD::Kernel::FdUnicodeString& placeholder, const FD::Kernel::Variant& val,
					JASParamType type );	
				///<summary>
				/// 绑定数据到指定的位置
				/// </summary>
				/// <para m name="pos">绑定位置的索引</param>
				/// <param name="val">待绑定的数据</param>
				/// <param name="type">绑定类型</param>
				///<returns>void</returns>
				void bindValue(INT32 pos, const FD::Kernel::Variant& val, JASParamType type);

				///<summary>
				/// 添加绑定数据到下一个绑定位置，按顺序绑定
				/// </summary>
				/// <param name="val">待绑定的数据</param>
				/// <param name="type">绑定类型</param>
				///<returns>void</returns>
				void addBindValue(const FD::Kernel::Variant& val, JASParamType type );

				///<summary>
				/// 返回指定位置的绑定数据
				/// </summary>
				/// <param name="placeholder">指定绑定位置的占位符</param>
				///<returns>已绑定的数据</returns>
				FD::Kernel::Variant boundValue(const FD::Kernel::FdUnicodeString& placeholder) const;
				///<summary>
				/// 返回指定位置的绑定数据
				/// </summary>
				/// <param name="pos">指定绑定位置的索引</param>
				///<returns>已绑定的数据</returns>
				FD::Kernel::Variant boundValue(INT32 pos) const;

				///<summary>
				/// 清空对象的所有状态
				/// </summary>
				///<returns>void</returns>
				void clear();
				///<summary>
				/// 返回driver
				/// </summary>
				///<returns>返回driver指针</returns>
				const FD::Utility::DB::CSqlDriver* driver() const;
				///<summary>
				/// 执行SQL语句
				/// </summary>
				/// <param name="query">SQL语句</param>
				///<returns>成功返回true，失败返回false</returns>
				bool exec(const FD::Kernel::FdUnicodeString& query);
				///<summary>
				/// 执行已准备好的SQL语句
				/// </summary>
				///<returns>成功返回true，失败返回false</returns>
				bool exec();
				///<summary>
				/// 执行已准备好的SQL语句,主要用于批量导入。
				/// </summary>
				///<returns>成功返回true，失败返回false</returns>
				bool execBatch ( FD::Utility::DB::JASBatchExecutionMode mode );
				///<summary>
				/// 返回已执行的SQL语句
				/// </summary>
				///<returns>已执行的SQL语句</returns>
				FD::Kernel::FdUnicodeString executedQuery() const;
				///<summary>
				/// 结束当前的数据库操作，清空当前操作状态
				/// </summary>
				///<returns>void</returns>
				void finish();
				///<summary>
				/// 索引到第一个select的结果
				/// </summary>
				///<returns>成功返回true，失败返回false</returns>
				bool first();
				///<summary>
				/// 索引到最后一个select的结果
				/// </summary>
				///<returns>成功返回true，失败返回false</returns>
				bool last();
				///<summary>
				/// 索引到下一个select的结果
				/// </summary>
				///<returns>成功返回true，失败返回false</returns>
				bool next();
				///<summary>
				/// 索引到上一个select的结果
				/// </summary>
				///<returns>成功返回true，失败返回false</returns>
				bool previous();
				///<summary>
				/// 是否是活动状态
				/// </summary>
				///<returns>是返回true，否返回false</returns>
				bool isActive() const;
				///<summary>
				/// 是否只支持前向查询
				/// </summary>
				///<returns>是返回true，否返回false</returns>
				bool isForwardOnly() const;

				//bool nextResult();

				///<summary>
				/// 索引到指定的位置
				/// </summary>
				/// <param name="index">索引的位置</param>
				/// <param name="relative">是否是相对当前的位置</param>
				///<returns>成功返回true，失败返回false</returns>
				bool seek(INT32 index, bool relative = false);
				///<summary>
				/// 返回result的引用
				/// </summary>
				///<returns>返回result指针</returns>
				const FD::Utility::DB::CSqlResult* result() const;
				///<summary>
				/// 返回当前的record
				/// </summary>
				///<returns>当前的record</returns>
				FD::Utility::DB::CSqlRecord record() const;
				///<summary>
				/// 返回当前记录中的指定字段的值
				/// </summary>
				/// <param name="index">字段的索引的位置</param>
				///<returns>返回字段的值</returns>
				FD::Kernel::Variant value(INT32 i) const;
				///<summary>
				/// 返回result的记录个数
				/// </summary>
				///<returns>成功返回记录个数，失败（可能数据库不支持，或者无法确定个数）返回-1</returns>
				INT32 size() const;
				///<summary>
				/// 当前是否是在有效的记录上
				/// </summary>
				///<returns>是返回true，否返回false</returns>
				bool isValid() const;
				///<summary>
				/// 当前记录的指定位置字段是否为空
				/// </summary>
				///<returns>是返回true，否返回false</returns>
				bool isNull(INT32 field) const;
				///<summary>
				/// 当前记录的位置
				/// </summary>
				///<returns>位置索引</returns>
				INT32 at() const;
				///<summary>
				/// 是否是查询状态
				/// </summary>
				///<returns>是返回true，否返回false</returns>
				bool isSelect() const;
				///<summary>
				/// 设置是否仅前向
				/// </summary>
				/// <param name="forward">是否</param>
				///<returns>void</returns>
				void setForwardOnly(bool forward);
				///<summary>
				/// 准备查询语句
				/// </summary>
				///<returns>成功返回true，失败返回false</returns>
				bool prepare(const FD::Kernel::FdUnicodeString& query);
				///<summary>
				/// 获取最后插入的记录的ID
				/// </summary>
				///<returns>返回包含ID的FD::Kernel::Variant</returns>
				FD::Kernel::Variant lastInsertId () const;
				///<summary>
				///返回sql操作对结果集影响的行数
				///</summary>
				///<param name=""></param>
				///<returns>sql操作对结果集影响的行数</returns>
				INT32 numRowsAffected() const;
				///<summary>
				///设置当前数据库的精度
				///</summary>
				///<param name="precisionPolicy">精度</param>
				///<returns></returns>
				void setNumericalPrecisionPolicy(JASNumericalPrecisionPolicy precisionPolicy);
				///<summary>
				///获取当前数据库的精度
				///</summary>
				///<param name=""></param>
				///<returns>精度值</returns>
				JASNumericalPrecisionPolicy numericalPrecisionPolicy() const;
				///<summary>
				///删除当前结果集并定位到下一个可用结果集
				///</summary>
				///<param name=""></param>
				///<returns>成功返回true,否则返回false</returns>
				bool nextResult();
			public:

				void bindValue(INT32 pos, std::vector<FD::Kernel::Variant>& vals, JASParamType type);

				void bindValue(const FD::Kernel::FdUnicodeString& placeholder, std::vector<FD::Kernel::Variant>& vals,
					JASParamType type );

				///<summary>
				/// 添加绑定数据到下一个绑定位置，按顺序绑定
				/// </summary>
				/// <param name="vals">待绑定的数据</param>
				/// <param name="type">绑定类型</param>
				///<returns>void</returns>
				void addBindValue(std::vector<FD::Kernel::Variant>& vals,JASParamType type );
			private:
				CSqlQueryPrivate *m_private;
			};

		} // namespace Database
	}
} 

#endif //_SQLQUERY_H_H_

